package com.iteaj.iot.server.websocket;

import com.iteaj.iot.server.ServerMessage;
import com.iteaj.iot.websocket.HttpRequestWrapper;
import com.iteaj.iot.websocket.WebSocketFrameType;
import com.iteaj.iot.websocket.WebSocketMessage;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;

import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;

public abstract class WebSocketServerMessageAbstract extends ServerMessage implements WebSocketServerMessage {

    private HttpRequest request;
    private WebSocketFrameType frameType;

    public WebSocketServerMessageAbstract(byte[] message) {
        super(message);
    }

    public WebSocketServerMessageAbstract(MessageHead head) {
        super(head);
    }

    public WebSocketServerMessageAbstract(MessageHead head, MessageBody body) {
        super(head, body);
    }

    @Override
    public String uri() {
        return ((HttpRequestWrapper) request()).getRawPath();
    }

    @Override
    public WebSocketVersion version() {
        return ((HttpRequestWrapper)request()).getVersion();
    }

    @Override
    public Optional<String> getHeader(String key) {
        return Optional.ofNullable(request().headers().get(key));
    }

    @Override
    public Optional<String> getQueryParam(String key) {
        String uri = this.request().uri();
        int indexOf = uri.indexOf("?");
        if(indexOf > 0) {
            String substring = uri.substring(0, indexOf);
            if(substring != null) {
                String collect = Arrays.stream(substring.split("&"))
                        .map(item -> item.split("="))
                        .filter(item -> item[0].equals(key))
                        .map(item -> item[1])
                        .collect(Collectors.joining(","));
                return Optional.ofNullable(collect);
            }
        }

        return Optional.empty();
    }

    @Override
    public WebSocketFrameType frameType() {
        return this.frameType;
    }

    public WebSocketServerMessageAbstract setFrameType(WebSocketFrameType frameType) {
        this.frameType = frameType;
        return this;
    }

    public WebSocketFrameType getFrameType() {
        return frameType;
    }

    @Override
    public HttpRequest request() {
        return this.request;
    }

    @Override
    public WebSocketMessage setRequest(HttpRequest request) {
        this.request = request;
        return this;
    }
}
